home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
726-750
/
742
/
rkrm_lib3
/
rkrm_lib3.lha
/
Expansion
/
autoboot.asm
next >
Wrap
Assembly Source File
|
1992-09-03
|
12KB
|
309 lines
*
* Copyright (c) 1992 Commodore-Amiga, Inc.
*
* This example is provided in electronic form by Commodore-Amiga, Inc. for
* use with the "Amiga ROM Kernel Reference Manual: Devices", 3rd Edition,
* published by Addison-Wesley (ISBN 0-201-56775-X).
*
* The "Amiga ROM Kernel Reference Manual: Devices" contains additional
* information on the correct usage of the techniques and operating system
* functions presented in these examples. The source and executable code
* of these examples may only be distributed in free electronic form, via
* bulletin board or as part of a fully non-commercial and freely
* redistributable diskette. Both the source and executable code (including
* comments) must be included, without modification, in any copy. This
* example may not be published in printed form or distributed with any
* commercial product. However, the programming techniques and support
* routines set forth in these examples may be used in the development
* of original executable software products for Commodore Amiga computers.
*
* All other rights reserved.
*
* This example is provided "as-is" and is subject to change; no
* warranties are made. All use is at your own risk. No liability or
* responsibility is assumed.
*
**********************************************************************
*
* Sample autoboot code fragment
*
**********************************************************************
**
**
** These are the calling conventions for the Diag routine
**
** A7 -- points to at least 2K of stack
** A6 -- ExecBase
** A5 -- ExpansionBase
** A3 -- your board's ConfigDev structure
** A2 -- Base of diag/init area that was copied
** A0 -- Base of your board
**
** Your Diag routine should return a non-zero value in D0 for success.
** If this value is NULL, then the diag/init area that was copied
** will be returned to the free memory pool.
**
INCLUDE "exec/types.i"
INCLUDE "exec/nodes.i"
INCLUDE "exec/resident.i"
INCLUDE "libraries/configvars.i"
; LVO's resolved by linking with library amiga.lib
XREF _LVOFindResident
ROMINFO EQU 1
ROMOFFS EQU $0
* ROMINFO defines whether you want the AUTOCONFIG information in
* the beginning of your ROM (set to 0 if you instead have PALS
* providing the AUTOCONFIG information instead)
*
* ROMOFFS is the offset from your board base where your ROMs appear.
* Your ROMs might appear at offset 0 and contain your AUTOCONFIG
* information in the high nibbles of the first $40 words ($80 bytes).
* Or, your autoconfig ID information may be in a PAL, with your
* ROMs possibly being addressed at some offset (for example $2000)
* from your board base. This ROMOFFS constant will be used as an
* additional offset from your configured board address when patching
* structures which require absolute pointers to ROM code or data.
*----- We'll store Version and Revision in serial number
VERSION EQU 37 ; also the high word of serial number
REVISION EQU 1 ; also the low word of serial number
* See the Addison-Wesley Amiga Hardware Manual for more info.
MANUF_ID EQU 2011 ; CBM assigned (2011 for hackers only)
PRODUCT_ID EQU 1 ; Manufacturer picks product ID
BOARDSIZE EQU $40000 ; How much address space board decodes
SIZE_FLAG EQU 3 ; Autoconfig 3-bit flag for BOARDSIZE
; 0=$800000(8meg) 4=$80000(512K)
; 1=$10000(64K) 5=$100000(1meg)
; 2=$20000(128K) 6=$200000(2meg)
; 3=$40000(256K) 7=$400000(4meg)
CODE
******* RomStart ***************************************************
**********************************************************************
RomStart:
IFGT ROMINFO
;
; ExpansionRom structure
;
; Note - If you implement your ExpansionRom and ExpansionControl
; with PALS, then you can comment out everything until DiagStart:
; (ie. Make ROMID EQU 0)
* ; High nibbles of first two words ($00,$02) are er_Type (not inverted)
; er_Type
dc.w $D000 ; 11xx normal board type
; xx0x not in memory free list
; xxx1 Diag valid (has driver)
dc.w (SIZE_FLAG<<12)&$7000 ; 0xxx not chained
; xnnn flags board size
* ; High nibbles of next two words are er_Product
* ; These are inverted (~), as are all other words except $40 and $42
; er_Product
dc.w (~(PRODUCT_ID<<8))&$f000,(~(PRODUCT_ID<<12))&$f000
; er_Flags
dc.w (~$C000)&$f000 ; ~1xxx board is moveable
; ~x1xx board can't be shut up
dc.w (~0)&$f000 ;
dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved03
; er_Manufacturer
dc.w (~(MANUF_ID))&$f000,(~(MANUF_ID<<4))&$f000
dc.w (~(MANUF_ID<<8))&$f000,(~(MANUF_ID<<12))&$f000
; er_SerialNumber
dc.w (~(VERSION))&$f000,(~(VERSION<<4))&$f000
dc.w (~(VERSION<<8))&$f000,(~(VERSION<<12))&$f000
dc.w (~(REVISION))&$f000,(~(REVISION<<4))&$f000
dc.w (~(REVISION<<8))&$f000,(~(REVISION<<12))&$f000
; er_InitDiagVec
dc.w (~((DiagStart-RomStart)))&$f000
dc.w (~((DiagStart-RomStart)<<4))&$f000
dc.w (~((DiagStart-RomStart)<<8))&$f000
dc.w (~((DiagStart-RomStart)<<12))&$f000
dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0c
dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0d
dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0e
dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0f
IFNE *-RomStart-$40
FAIL "ExpansionRom structure not the right size"
ENDC
;Note: nibbles $40 and $42 are not to be inverted
dc.w (0)&$f000,(0)&$f000 ; ec_Interrupt (no interrupts)
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved11
dc.w (~0)&$f000,(~0)&$f000 ; ec_BaseAddress (write only)
dc.w (~0)&$f000,(~0)&$f000 ; ec_Shutup (write only)
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved14
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved15
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved16
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved17
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved18
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved19
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1a
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1b
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1c
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1d
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1e
dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1f
IFNE *-RomStart-$80
FAIL "Expansion Control structure not the right size"
ENDC
ENDC ;ROMINFO
******* DiagStart **************************************************
DiagStart: ; This is the DiagArea structure whose relative offset from
; your board base appears as the Init Diag vector in your
; autoconfig ID information. This structure is designed
; to use all relative pointers (no patching needed).
dc.b DAC_WORDWIDE+DAC_CONFIGTIME ; da_Config
dc.b 0 ; da_Flags
dc.w EndCopy-DiagStart ; da_Size
dc.w DiagEntry-DiagStart ; da_DiagPoint
dc.w BootEntry-DiagStart ; da_BootPoint
dc.w DevName-DiagStart ; da_Name
dc.w 0 ; da_Reserved01
dc.w 0 ; da_Reserved02
******* Resident Structure *****************************************
Romtag:
dc.w RTC_MATCHWORD ; UWORD RT_MATCHWORD
rt_Match: dc.l Romtag-DiagStart ; APTR RT_MATCHTAG
rt_End: dc.l EndCopy-DiagStart ; APTR RT_ENDSKIP
dc.b RTW_COLDSTART ; UBYTE RT_FLAGS
dc.b VERSION ; UBYTE RT_VERSION
dc.b NT_DEVICE ; UBYTE RT_TYPE
dc.b 20 ; BYTE RT_PRI
rt_Name: dc.l DevName-DiagStart ; APTR RT_NAME
rt_Id: dc.l IdString-DiagStart ; APTR RT_IDSTRING
rt_Init: dc.l Init-RomStart ; APTR RT_INIT
******* Strings referenced in Diag Copy area ************************
DevName: dc.b 'abc.device',0 ; Name string
IdString dc.b 'abc ',48+VERSION,'.',48+REVISION ; Id string
DosName: dc.b 'dos.library',0 ; DOS library name
DosDevName: dc.b 'ABC',0 ; dos device name for MakeDosNode()
; (dos device will be ABC:)
ds.w 0 ; word align
******* DiagEntry **************************************************
**********************************************************************
*
* success = DiagEntry(BoardBase,DiagCopy, configDev)
* d0 a0 a2 a3
*
* Called by expansion architecture to relocate any pointers
* in the copied diagnostic area. We will patch the romtag.
* If you have pre-coded your MakeDosNode packet, BootNode,
* or device initialization structures, they would also need
* to be within this copy area, and patched by this routine.
*
**********************************************************************
DiagEntry:
lea patchTable-RomStart(a0),a1 ; find patch table
adda.l #ROMOFFS,a1 ; adjusting for ROMOFFS
* Patch relative pointers to labels within DiagCopy area
* by adding Diag RAM copy address. These pointers were coded as
* long relative offsets from base of the DiagArea structure.
*
dpatches:
move.l a2,d1 ;d1=base of ram Diag copy
dloop:
move.w (a1)+,d0 ;d0=word offs. into Diag needing patch
bmi.s bpatches ;-1 is end of word patch offset table
add.l d1,0(a2,d0.w) ;add DiagCopy addr to coded rel. offset
bra.s dloop
* Patches relative pointers to labels within the ROM by adding
* the board base address + ROMOFFS. These pointers were coded as
* long relative offsets from RomStart.
bpatches:
move.l a0,d1 ;d1 = board base address
add.l #ROMOFFS,d1 ;add offset to where your ROMs are
rloop:
move.w (a1)+,d0 ;d0=word offs. into Diag needing patch
bmi.s endpatches ;-1 is end of patch offset table
add.l d1,0(a2,d0.w) ;add ROM address to coded relative offset
bra.s rloop
endpatches:
moveq.l #1,d0 ; indicate "success"
rts
******* BootEntry **************************************************
**********************************************************************
BootEntry: lea DosName(PC),a1 ; 'dos.library',0
jsr _LVOFindResident(a6) ; find the DOS resident tag
move.l d0,a0 ; in order to bootstrap
move.l RT_INIT(A0),a0 ; set vector to DOS INIT
jsr (a0) ; and initialize DOS
rts
*
* End of the Diag copy area which is copied to RAM
*
EndCopy:
*************************************************************************
*************************************************************************
*
* Beginning of rom driver code and data that is accessed only in
* the rom space. This must all be position-independent.
*
patchTable:
* Word offsets into Diag area where pointers need Diag copy address added
dc.w rt_Match-DiagStart
dc.w rt_End-DiagStart
dc.w rt_Name-DiagStart
dc.w rt_Id-DiagStart
dc.w -1
* Word offsets into Diag area where pointers need boardbase+ROMOFFS added
dc.w rt_Init-DiagStart
dc.w -1
******* Romtag InitEntry **********************************************
*************************************************************************
Init: ; After Diag patching, our romtag will point to this
; routine in ROM so that it can be called at Resident
; initialization time.
; This routine will be similar to a normal expansion device
; initialization routine, but will MakeDosNode then set up a
; BootNode, and Enqueue() on eb_MountList.
;
rts
; Rest of your position-independent device code goes here.
END